﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="RejectControllerTests.cs" company="DST Nexdox">
//   Copyright (c) DST Nexdox. All rights reserved.
// </copyright>
// <summary>
//   Defines the RejectControllerTests type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace UnityWebTests.Controllers
{
  using System;
  using System.Collections.Generic;
  using System.Web.Mvc;
  using Entities;
  using Exceptions;
  using FluentAssertions;
  using Logging;
  using Moq;
  using NUnit.Framework;
  using ServiceInterfaces;
  using UnityWeb.Controllers;
  using UnityWeb.Models.Rejection;
  using UnityWeb.Models.Shared;

  [TestFixture]
  public class RejectControllerTests : ControllerTestsBase
  {
    private Mock<IRejectionService> rejectionService;
    private Mock<IDocumentService> documentService;
    private Mock<ILogger> logger; 
    private RejectController rejectController;
    private RejectDocumentsViewModel rejectDocumentsViewModel;

    [SetUp]
    public void SetUp()
    {
      this.rejectionService = new Mock<IRejectionService>();
      this.documentService = new Mock<IDocumentService>();
      this.logger = new Mock<ILogger>();
      this.rejectController = new RejectController(this.rejectionService.Object, this.documentService.Object, this.logger.Object);

      this.rejectDocumentsViewModel = new RejectDocumentsViewModel
      {
        RejectDocumentViewModel = new List<RejectDocumentViewModel>
                                                                    {
                                                                      new RejectDocumentViewModel
                                                                        {
                                                                          DocumentId = "guid1",
                                                                          Selected = true
                                                                        },
                                                                        new RejectDocumentViewModel
                                                                        {
                                                                          DocumentId = "guid2",
                                                                          Selected = false
                                                                        }
                                                                    },
                                                                    Grid = "grid",
                                                                    Page = "1"
      };

      this.SetControllerContext(this.rejectController);
      MockHttpContext.SetupGet(x => x.Session["CartId"]).Returns("testUser");
      MockHttpContext.SetupGet(x => x.User.Identity.Name).Returns("testUser");
      MockHttpContext.SetupGet(x => x.Session["testUser"]).Returns("testUser");
    }

    [Test]
    public void GivenARejectController_WhenITryToRejectADocument_AndTheDocumentIsAlreadyRejected_IGetTheCorrectViewReturned()
    {
      this.rejectionService.Setup(
        a =>
        a.RejectDocument(
          It.IsAny<String>(),
          "guid1")).Throws<DocumentAlreadyRejectedException>();

      var result = (PartialViewResult)this.rejectController.Document(this.rejectDocumentsViewModel);
      var model = (DocumentWarningsViewModel)result.Model;
      model.DocumentsAlreadyRejected.Should().Be("guid1");
      model.DocumentsAlreadyApproved.Should().Be(String.Empty);
      model.DocumentsApproved.Should().Be(0);
      model.DocumentsRejected.Should().Be(0);
      result.ViewName.Should().Be("_DocumentWarnings");
    }

    [Test]
    public void GivenARejectController_WhenITryToRejectADocument_AndTheDocumentIsAlreadyApproved_IGetTheCorrectViewReturned()
    {
      this.rejectionService.Setup(
        a =>
        a.RejectDocument(
          It.IsAny<String>(),
          "guid1")).Throws<DocumentAlreadyApprovedException>();

      var result = (PartialViewResult)this.rejectController.Document(this.rejectDocumentsViewModel);
      var model = (DocumentWarningsViewModel)result.Model;
      model.DocumentsAlreadyRejected.Should().Be(string.Empty);
      model.DocumentsAlreadyApproved.Should().Be("guid1");
      model.DocumentsApproved.Should().Be(0);
      model.DocumentsRejected.Should().Be(0);
      result.ViewName.Should().Be("_DocumentWarnings");
    }

    [Test]
    public void GivenARejectController_WhenITryToRejectADocument_IGetTheCorrectViewReturned()
    {
      this.rejectionService.Setup(
        a =>
        a.RejectDocument(
          "guid1",
          It.IsAny<String>()));

      var result = (PartialViewResult)this.rejectController.Document(this.rejectDocumentsViewModel);
      var model = (DocumentWarningsViewModel)result.Model;
      model.DocumentsAlreadyApproved.Should().Be(String.Empty);
      model.DocumentsAlreadyRejected.Should().Be(String.Empty);
      model.DocumentsApproved.Should().Be(0);
      model.DocumentsRejected.Should().Be(1);
      result.ViewName.Should().Be("_DocumentWarnings");
    }

    [Test]
    public void GivenARejectController_WhenITryToRejectAGrid_AndTheGridContaintsADocumentThatAreAlreadyRejected_IGetTheCorrectViewReturned()
    {
      var rejectionResults = new BatchApprovalResults();
      rejectionResults.AlreadyRejectedDocuments.Add("guid1");

      this.rejectionService.Setup(service => service.RejectGrid(It.IsAny<String>(), It.IsAny<String>()))
        .Returns(rejectionResults);

      var result = (PartialViewResult)this.rejectController.Grid("grid");
      var model = (DocumentWarningsViewModel)result.Model;
      model.DocumentsAlreadyApproved.Should().Be(String.Empty);
      model.DocumentsAlreadyRejected.Should().Be("guid1");
      model.DocumentsApproved.Should().Be(0);
      model.DocumentsRejected.Should().Be(0);
      result.ViewName.Should().Be("_DocumentWarnings");
    }

    [Test]
    public void GivenARejectController_WhenITryToRejectAGrid_AndTheGridContaintsADocumentThatIsAlreadyApproved_IGetTheCorrectViewReturned()
    {
      var rejectionResults = new BatchApprovalResults();
      rejectionResults.AlreadyApprovedDocuments.Add("guid1");

      this.rejectionService.Setup(service => service.RejectGrid(It.IsAny<String>(), It.IsAny<String>()))
        .Returns(rejectionResults);

      var result = (PartialViewResult)this.rejectController.Grid("grid");
      var model = (DocumentWarningsViewModel)result.Model;
      model.DocumentsAlreadyRejected.Should().Be(string.Empty);
      model.DocumentsAlreadyApproved.Should().Be("guid1");
      model.DocumentsApproved.Should().Be(0);
      model.DocumentsRejected.Should().Be(0);
      result.ViewName.Should().Be("_DocumentWarnings");
    }

    [Test]
    public void GivenARejectController_WhenITryToRejectAGrid_IGetTheCorrectViewReturned()
    {
      var rejectionResults = new BatchApprovalResults();
      rejectionResults.ApprovedDocuments.Add("guid1");

      this.rejectionService.Setup(service => service.RejectGrid(It.IsAny<String>(), It.IsAny<String>()))
        .Returns(rejectionResults);

      var result = (PartialViewResult)this.rejectController.Grid("grid");
      var model = (DocumentWarningsViewModel)result.Model;
      model.DocumentsAlreadyApproved.Should().Be(String.Empty);
      model.DocumentsAlreadyRejected.Should().Be(String.Empty);
      model.DocumentsApproved.Should().Be(0);
      model.DocumentsRejected.Should().Be(1);
      result.ViewName.Should().Be("_DocumentWarnings");
    }

    [Test]
    public void GivenARejectController_WhenITryToRejectABasket_AndTheGridContaintsADocumentThatAreAlreadyApproved_IGetTheCorrectViewReturned()
    {
      var rejectionResults = new BatchApprovalResults();
      rejectionResults.ApprovedDocuments.Add("guid1");
      rejectionResults.AlreadyApprovedDocuments.Add("guid2");

      this.rejectionService.Setup(service => service.RejectBasket(It.IsAny<String>(), It.IsAny<String>()))
        .Returns(rejectionResults);

      var result = (PartialViewResult)this.rejectController.Basket(this.rejectDocumentsViewModel);
      var model = (DocumentWarningsViewModel)result.Model;
      model.DocumentsAlreadyApproved.Should().Be("guid2");
      model.DocumentsAlreadyRejected.Should().Be(String.Empty);
      model.DocumentsRejected.Should().Be(1);
      result.ViewName.Should().Be("_DocumentWarnings");
    }

    [Test]
    public void GivenARejectController_WhenITryToRejectABasket_AndTheGridContaintsADocumentThatIsAlreadyRejected_IGetTheCorrectViewReturned()
    {
      var rejectionResults = new BatchApprovalResults();
      rejectionResults.ApprovedDocuments.Add("guid1");
      rejectionResults.AlreadyRejectedDocuments.Add("guid2");

      this.rejectionService.Setup(service => service.RejectBasket(It.IsAny<String>(), It.IsAny<String>()))
        .Returns(rejectionResults);

      var result = (PartialViewResult)this.rejectController.Basket(this.rejectDocumentsViewModel);
      var model = (DocumentWarningsViewModel)result.Model;
      model.DocumentsAlreadyApproved.Should().Be(String.Empty);
      model.DocumentsAlreadyRejected.Should().Be("guid2");
      model.DocumentsApproved.Should().Be(0);
      model.DocumentsRejected.Should().Be(1);
      result.ViewName.Should().Be("_DocumentWarnings");
    }

    [Test]
    public void GivenARejectController_WhenITryToRejectABasket_IGetTheCorrectViewReturned()
    {
      var rejectionResults = new BatchApprovalResults();
      rejectionResults.ApprovedDocuments.Add("guid1");
      rejectionResults.ApprovedDocuments.Add("guid2");

      this.rejectionService.Setup(service => service.RejectBasket(It.IsAny<String>(), It.IsAny<String>()))
        .Returns(rejectionResults);

      var result = (PartialViewResult)this.rejectController.Basket(this.rejectDocumentsViewModel);
      var model = (DocumentWarningsViewModel)result.Model;
      model.DocumentsAlreadyApproved.Should().Be(String.Empty);
      model.DocumentsApproved.Should().Be(0);
      model.DocumentsRejected.Should().Be(2);
      result.ViewName.Should().Be("_DocumentWarnings");
    }
  }
}
